package com.ssy.lingxi.contract.serviceimpl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateUtil;
import com.querydsl.core.BooleanBuilder;
import com.querydsl.core.types.Projections;
import com.querydsl.jpa.impl.JPAQuery;
import com.querydsl.jpa.impl.JPAQueryFactory;
import com.ssy.lingxi.common.model.dto.UserLoginCacheDTO;
import com.ssy.lingxi.common.response.PageData;
import com.ssy.lingxi.common.response.Wrapper;
import com.ssy.lingxi.contract.entity.ContractOuterRecordDO;
import com.ssy.lingxi.contract.entity.QContractDO;
import com.ssy.lingxi.contract.entity.QContractOuterRecordDO;
import com.ssy.lingxi.contract.model.dto.OperateLogInputDto;
import com.ssy.lingxi.contract.model.dto.OperateLogOuterResponDto;
import com.ssy.lingxi.contract.model.vo.common.request.ContractOuterRecordPageVO;
import com.ssy.lingxi.contract.model.vo.common.response.ContractOuterRecordVO;
import com.ssy.lingxi.contract.repository.ContractOuterRecordRepository;
import com.ssy.lingxi.contract.service.IContractOuterRecordService;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 合同外部流转记录接口实现
 * @author 伍将
 * @date 2021/2/7
 * @version 2.0.0
 */
@Service
public class ContractOuterRecordServiceImpl implements IContractOuterRecordService {

    @Resource
    private ContractOuterRecordRepository outerRecordRepository;
    @Resource
    private JPAQueryFactory jpaQueryFactory;

    /**
     * 新增外部流转记录
     * @author 伍将
     * @date 2021/2/7
     * @param user: 新增外部流转记录
     * @param contractId: 合同id
     * @param status: 状态
     * @param statusName: 状态名称
     * @param operate: 操作
     * @param opinion: 意见
     * @return 操作结果
     **/
    @Override
    public Wrapper<Void> add(UserLoginCacheDTO user, Long contractId, Integer status, String statusName, String operate, String opinion) {

        ContractOuterRecordDO recordDO = new ContractOuterRecordDO();
        recordDO.setContractId(contractId);
        recordDO.setUserId(user.getUserId());
        recordDO.setMemberId(user.getMemberId());
        recordDO.setRoleId(user.getMemberRoleId());
        recordDO.setRoleName(user.getMemberRoleName());
        recordDO.setStatus(status);
        recordDO.setStatusName(statusName);
        recordDO.setOperate(operate);
        recordDO.setOperateTime(System.currentTimeMillis());
        recordDO.setOpinion(opinion);

        outerRecordRepository.saveAndFlush(recordDO);

        return Wrapper.success();
    }

    /**
     * 分页查询合同外部流转记录
     * @author 伍将
     * @date 2021/2/24
     * @param pageVO: 分页请求参数
     * @return 操作结果
     **/
    @Override
    public Wrapper<PageData<ContractOuterRecordVO>> pageList(ContractOuterRecordPageVO pageVO) {
        // 组装查询条件
        OperateLogInputDto dto=new OperateLogInputDto();
        dto.setContractId(pageVO.getContractId());
        dto.setPageSize(pageVO.getPageSize());
        dto.setCurrent(pageVO.getCurrent());
        PageData<OperateLogOuterResponDto> pageData = pageListCommon(null, dto);
        List<ContractOuterRecordVO> resultList =null;
        if(CollectionUtil.isNotEmpty(pageData.getData())){
            resultList=pageData.getData().stream().map(r ->{
                ContractOuterRecordVO entity = new ContractOuterRecordVO();
                entity.setRoleName(r.getRoleName());
                entity.setStatus(r.getStatus());
                entity.setStatusName(r.getStatusName());
                entity.setOperate(r.getOperate());
                entity.setOperateTime(DateUtil.format(DateUtil.date(r.getOperateTime()), "yyyy-MM-dd HH:mm"));
                entity.setOpinion(r.getOpinion());
                return entity;
            }).collect(Collectors.toList());
        }
        return Wrapper.success(new PageData<>(pageData.getTotalCount(), resultList));
    }

    /**
     * 分页查询合同外部流转记录
     * @author 伍将
     * @date 2021/2/24
     * @param pageVO: 分页请求参数
     * @return 操作结果
     **/
    public PageData<OperateLogOuterResponDto> pageListCommon(UserLoginCacheDTO loginUser, OperateLogInputDto pageVO){
        // 查询表实体
        QContractDO contractDO=QContractDO.contractDO;
        QContractOuterRecordDO contractOuterRecordDO=QContractOuterRecordDO.contractOuterRecordDO;
        // 查询条件构造
        BooleanBuilder predicates = new BooleanBuilder();
        //合同id
        if(pageVO.getContractId()!=null){
            predicates.and(contractDO.id.eq(pageVO.getContractId()));
        }
        //合同编号
        if(StringUtils.hasLength(pageVO.getContractNo())){
            predicates.and(contractDO.contractNo.eq(pageVO.getContractNo()));
        }
        //时间
        if(pageVO.getStartTime()!=null){
            predicates.and(contractOuterRecordDO.operateTime.goe(pageVO.getStartTime()));
        }
        if(pageVO.getEndTime()!=null){
            predicates.and(contractOuterRecordDO.operateTime.loe(pageVO.getEndTime()));
        }
        //会员id
        if(loginUser!=null){
            predicates.and(contractOuterRecordDO.memberId.eq(loginUser.getMemberId()));
            predicates.and(contractOuterRecordDO.roleId.eq(loginUser.getMemberRoleId()));
        }
        // 关联查询
        JPAQuery<OperateLogOuterResponDto> query = jpaQueryFactory
                .select(Projections.bean(OperateLogOuterResponDto.class,
                        contractDO.contractNo,
                        contractOuterRecordDO.roleName,
                        contractOuterRecordDO.status,
                        contractOuterRecordDO.statusName,
                        contractOuterRecordDO.operate,
                        contractOuterRecordDO.operateTime,
                        contractOuterRecordDO.opinion)
                )
                .from(contractDO)
                .innerJoin(contractOuterRecordDO)
                .on(contractDO.id.eq(contractOuterRecordDO.contractId))
                .where(predicates);

        long totalCount = query.fetchCount();
        List<OperateLogOuterResponDto> responses = query.orderBy(contractOuterRecordDO.operateTime.desc())
                .offset(pageVO.getCurrentOffset())
                .limit(pageVO.getPageSize())
                .fetch();
        return new PageData<>(totalCount, responses);
    }
}
